﻿using BrightIdeasSoftware;
using Rename.Util;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Rename.UC.FastOLSV
{
    public partial class UcFastOlsvBase : UserControl
    {
        private List<LsvFileBase> _lsvFileInfo = new List<LsvFileBase>();
        protected const string DATE_FORMATE = "yyyy-MM-dd HH:mm:ss";
        protected BrightIdeasSoftware.OLVColumn 操作 = new BrightIdeasSoftware.OLVColumn();
        private EventHandler<RowsCountChangeEventArgs> _rowsCountChange=null;
        

        public UcFastOlsvBase()
        {
            InitializeComponent();

            fastOlsv.RowHeight = 40; //行高
            fastOlsv.UseCompatibleStateImageBehavior = false;
            fastOlsv.UseFiltering = true;//过滤器
            fastOlsv.FullRowSelect = true;//整行选择
            fastOlsv.MultiSelect = true;  //选择多行
            fastOlsv.CellEditActivation = ObjectListView.CellEditActivateMode.SingleClick;//编辑模式
            fastOlsv.EmptyListMsg = "信息为空值";
            fastOlsv.AlternateRowBackColor = Color.FromArgb(192, 255, 192);//颜色交替出现
            fastOlsv.UseAlternatingBackColors = true;
            fastOlsv.AllowDrop = true;
            fastOlsv.DragSource = new SimpleDragSource();
            fastOlsv.DropSink = new RearrangingDropSink(true);

            //fastOlsv.UseTranslucentHotItem = true; //移入行高亮
            //fastOlsv.Invalidate();
            //fastOlsv.HotItemStyle.Overlay = new BusinessCardOverlay();
            //fastOlsv.HotItemStyle = fastOLsv.HotItemStyle;

            sImgList.Images.Add("file", Properties.Resources.文件);
            sImgList.Images.Add("folder", Properties.Resources.文件夹);

            fastOlsv.ButtonClick += FastOlsv_ButtonClick;
            fastOlsv.CellEditValidating += FastOlsv_CellEditValidating;
            fastOlsv.CellEditFinished += FastOlsv_CellEditFinished;

            SetupColumns();
        }
        string hisNewVal = "";
        private void FastOlsv_CellEditFinished(object sender, CellEditEventArgs e)
        {
            // 1. 获取编辑后的行数据对象（绑定的实体）
            var editedData = e.RowObject as LsvFileBase;
            if (editedData == null) return;

            string newVal = e.NewValue.ToString();
            if (newVal == hisNewVal) return;
            
            string fileName = e.ListViewItem.Text;
            string ext = Path.GetExtension(fileName);
            editedData.NewFileName = $"{e.NewValue}{ext}";
            fastOlsv.RefreshObject(editedData);
        }

        private void FastOlsv_CellEditValidating(object sender, CellEditEventArgs e)
        {
            string newVal = e.NewValue.ToString();
            hisNewVal = ((LsvFileBase)e.RowObject).NewFileName;
            string notInFileChar=FileHelper.IsSpecialChar(newVal);
            if (string.IsNullOrEmpty(notInFileChar)==false)
            {
                MessageBox.Show($"文件名:{newVal} 不能包含 {notInFileChar} 字符");
            }
        }
        //public FastObjectListView FastOlsv
        //{
        //    get => fastOlsv;
        //}
        public static UcFastOlsvBase Create(OLSVType type)
        {
            switch (type)
            {
                case OLSVType.图片重命名:return new UcFastOlsv图片重命名();
                case OLSVType.文件重命名:return new UcFastOlsv文件重命名();
                case OLSVType.文件夹重命名:return new UcFastOlsv文件夹重命名();
                case OLSVType.文件时间属性:return new UcFastOlsv文件时间属性();
                case OLSVType.文件夹时间属性:return new UcFastOlsv文件夹时间属性();
                case OLSVType.提取文件名称:return new UcFastOlsv提取文件名称();
                case OLSVType.提取文件夹名称:return new UcFastOlsv提取文件夹名称();
                case OLSVType.批量新建文件夹:return new UcFastOlsv批量新建文件夹();
                default:return new UcFastOlsvBase();
            }
        }

        #region  公有方法
        public event EventHandler<RowsCountChangeEventArgs> RowsCountChange
        {
            add
            {
                _rowsCountChange += value;
                //Console.WriteLine(value.ToString());
            }
            remove
            {
                _rowsCountChange -= value;
            }
        }

        public void Clear()
        {
            _lsvFileInfo.Clear();
            fastOlsv.ClearObjects();
            OnRowsCountChange(new RowsCountChangeEventArgs() { RowsCount = fastOlsv.Items.Count,ListCount=_lsvFileInfo.Count });
            fastOlsv.EmptyListMsg = "点击 / 拖拽文件到此区域";
        }

        public int RowsCount
        {
            get => fastOlsv.Items.Count;
        }

        public void Filter(string keyword, string type)
        {
            TextMatchFilter filter = null;
            if (!string.IsNullOrEmpty(keyword))
            {
                if (type == "首字符")
                {
                    filter = TextMatchFilter.Prefix(fastOlsv, keyword);
                }
                else if (type == "任意字符")
                {
                    filter = TextMatchFilter.Contains(fastOlsv, keyword);
                }
                else if (type == "正则字符")
                {
                    filter = TextMatchFilter.Regex(fastOlsv, keyword);
                }
            }
            if (this.fastOlsv.DefaultRenderer == null)
                this.fastOlsv.DefaultRenderer = new HighlightTextRenderer(filter);
            this.fastOlsv.AdditionalFilter = filter;
            OnRowsCountChange(new RowsCountChangeEventArgs() { RowsCount = fastOlsv.Items.Count, ListCount = _lsvFileInfo.Count });
        }
        public void SetDataSource(string[] fileNams, string rule, Action<int> action)
        {
            Task.Run(() => {
                try
                {
                    foreach (string item in fileNams)
                    {
                        LsvFileBase file_info = AddRow(item, rule);
                        file_info.Status = "待操作";
                        _lsvFileInfo.Add(file_info);
                        action(_lsvFileInfo.Count);
                    }
                }
                catch (Exception ex)
                {
                    fastOlsv.EmptyListMsg = ex.Message;
                    Console.WriteLine(ex.ToString());
                }
                finally
                {
                    fastOlsv.SetObjects(_lsvFileInfo);
                    //OnRowsCountChange(new RowsCountChangeEventArgs() { RowsCount = fastOlsv.Items.Count });
                }
            });
        }

        public void SetNewFileName(string newFileName)
        {
            foreach(LsvFileBase item in _lsvFileInfo)
            {
                if (string.IsNullOrEmpty(newFileName) == true)
                {
                    item.NewFileName = item.FileName;
                }
                else
                {
                    string ext = Path.GetExtension(item.NewFileName);
                    item.NewFileName = newFileName + ext;
                }
            }
            fastOlsv.SetObjects(_lsvFileInfo);
        }

        public async Task<List<LsvFileBase>> SetDataSourceAsnyc(string[] fileNams, string rule, Action<int> action)
        {
            await Task.Run(() => {
                try
                {
                    foreach (string item in fileNams)
                    {
                        LsvFileBase file_info = AddRow(item, rule);
                        file_info.Status = "待操作";
                        _lsvFileInfo.Add(file_info);
                        action(_lsvFileInfo.Count);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    fastOlsv.EmptyListMsg = ex.Message;
                }
                finally
                {
                    fastOlsv.SetObjects(_lsvFileInfo);
                    //OnRowsCountChange(new RowsCountChangeEventArgs() { RowsCount = fastOlsv.Items.Count });
                }
            });
            return _lsvFileInfo;
        }

        #endregion

        #region 虚方法
        protected virtual void OnRowsCountChange(RowsCountChangeEventArgs e)
        {
            var temp = System.Threading.Volatile.Read(ref _rowsCountChange);
            if (temp != null)
            {
                temp(this,e);
            }
        }
        protected virtual void SetupColumns()
        {
            this.操作.AspectName = "Actions";
            this.操作.IsEditable = false;
            this.操作.Text = "操作";
            this.操作.HeaderTextAlign = HorizontalAlignment.Center;
            this.操作.Width = 180;
            this.操作.IsButton = true;

            MultiButtonRenderer render = new MultiButtonRenderer();
            render.ButtonImages.Add(Properties.Resources.删除按钮);
            render.ButtonImages.Add(Properties.Resources.文件夹按钮);

            render.ButtonActions.Add(ButtonImage);
            render.ButtonActions.Add(ButtonImage);

            this.操作.Renderer = render;
            fastOlsv.AllColumns.Add(this.操作);

        }

        protected virtual LsvFileBase AddRow(string file, string rule)
        {
            throw new NotImplementedException("AddRow方法未实现");
        }

        protected virtual Object GetFileIcon(Object row)
        {
            LsvFileBase fileIcon = row as LsvFileBase;
            string ext = Path.GetExtension(fileIcon.FileName).TrimStart('.');
            if (ext == "")
            {
                return sImgList.Images.IndexOfKey("file");
            }
            else
            {
                string fileName = $"{fileIcon.Path.TrimEnd('\\')}\\{fileIcon.FileName}";
                if (ext == "exe")  //EXE文件单独处理，每个不同EXE可能图标不同
                {
                    int idx = sImgList.Images.IndexOfKey(fileName);
                    if (idx >= 0) return idx;
                    Icon icon = FileIconExtractor.GetFileIcon(fileName);
                    sImgList.Images.Add(fileName, icon);
                    return sImgList.Images.Count;
                }
                else
                {
                    int idx = sImgList.Images.IndexOfKey(ext);
                    if (idx >= 0) return idx;
                    Icon icon = FileIconExtractor.GetFileIcon(fileName);
                    sImgList.Images.Add(ext, icon);
                    return sImgList.Images.Count;
                }
            }
        }
        #endregion

        #region 私有方法
        private void FastOlsv_ButtonClick(object sender, CellClickEventArgs e)
        {
            var renderer = e.Column.Renderer as MultiButtonRenderer;
            Console.WriteLine($"{renderer} {e.RowIndex}");
            if (renderer != null && e.HitTest.UserData is int buttonIndex)
            {
                if (buttonIndex >= 0 && buttonIndex < renderer.ButtonActions.Count)
                {
                    renderer.ButtonActions[buttonIndex]?.Invoke(e.HitTest);
                }
            }

            Console.WriteLine($"FastOlsv_ButtonClick={e.HitTest.UserData}");
        }
        private void ButtonImage(OlvListViewHitTestInfo hitTest)
        {
            if (hitTest.UserData.ToString() == "0") //删除
            {
                var row = _lsvFileInfo.FirstOrDefault(t => t.FileName == hitTest.Item.Text);
                if (row == null) return;
                fastOlsv.RemoveObject(hitTest.RowObject);
                _lsvFileInfo.Remove(row);
                OnRowsCountChange(new RowsCountChangeEventArgs() { RowsCount = fastOlsv.Items.Count,ListCount= _lsvFileInfo.Count });
            }
            else if (hitTest.UserData.ToString() == "1")  //查看
            {
                LsvFileBase lsvFile = hitTest.Item.RowObject as LsvFileBase;
                string fileName = $"{lsvFile.Path.TrimEnd('\\')}\\{lsvFile.FileName}";
                // 使用资源管理器打开目录并选中文件
                Process.Start(new ProcessStartInfo { FileName = "explorer.exe", Arguments = $"/select, \"{fileName}\"", UseShellExecute = true });
            }
            else
            {

            }
        }
        #endregion
    }
}
